//
//  CLAudioPlayer+Extensions.swift
//  clreader
//
//  Created by colin on 2019/4/9.
//  Copyright © 2019 colin. All rights reserved.
//

import AVKit
import MediaPlayer
import Kingfisher

//MARK: - 媒体信息配置
extension CLAudioPlayer {
    
    /// 配置多媒体控制面板的显示页面
    func mediaItemArtwork() {
        
        if let currentAudio = self.current.value {
            
            // 设置后台播放时显示的东西，例如歌曲名字，图片等
            var info = JSONObject()
            
            ///标题
            info[MPMediaItemPropertyTitle] = currentAudio.title
            ///作者
            info[MPMediaItemPropertyArtist] = "colin"
            //相簿标题
            info[MPMediaItemPropertyAlbumTitle] = "相册标题"

            //当前播放进度 （会被自动计算出来，自动计算与MPNowPlayingInfoPropertyPlaybackRate设置的速率正相关)
            info[MPNowPlayingInfoPropertyElapsedPlaybackTime] = self.currentTime
            
            //调整外部显示的播放速率正常为1、一般都是根据内部播放器的播放速率作同步，一般不必修改
            // info[MPNowPlayingInfoPropertyPlaybackRate] = 1
            
            //播放总时间 由当前播放的资源提供
            info[MPMediaItemPropertyPlaybackDuration] = self.totalTime
            
            // 封面图片
            if let coverImage = KingfisherManager.shared.cache.retrieveImageInDiskCache(forKey: currentAudio.cover_url) {
                ///封面
                let artWork = MPMediaItemArtwork(boundsSize: coverImage.size, requestHandler: { (size) -> UIImage in
                    return coverImage
                })
                info[MPMediaItemPropertyArtwork] = artWork
            } else {
                // 下载图片
                if let imageUrl = URL(string: currentAudio.cover_url) {
                    KingfisherManager.shared.downloader.downloadImage(with: imageUrl, retrieveImageTask: nil, options: nil, progressBlock: { (receivedSize, totalSize) in
                        
                    }) { (img, err, url, data) in
                        if let img_ = img, let key = url?.absoluteString {
                            //存入本地磁盘
                            KingfisherManager.shared.cache.store(img_, forKey: key)
                        }
                    }
                }

            }
            
            MPNowPlayingInfoCenter.default().nowPlayingInfo = info

            
        }
        
    }
    
    //MARK: - 远程控制配置
    ///配置远程控制显示的信息
    func configRemoteCommandCenter() {
        
        let remoteCommandCenter = MPRemoteCommandCenter.shared()
        
        //播放事件
        let playCommand = remoteCommandCenter.playCommand
        playCommand.isEnabled = true
        playCommand.addTarget { [weak self] (event) -> MPRemoteCommandHandlerStatus in
            self?.startOrResume()
            return .success
        }
        
        //暂停事件
        let pauseCommand = remoteCommandCenter.pauseCommand
        pauseCommand.isEnabled = true
        pauseCommand.addTarget { [weak self] (event) -> MPRemoteCommandHandlerStatus in
            self?.pause()
            return .success
        }
        
        //上一曲
        let preTrackCommand = remoteCommandCenter.previousTrackCommand
        preTrackCommand.isEnabled = true
        preTrackCommand.addTarget { [weak self] (event) -> MPRemoteCommandHandlerStatus in
            self?.playPre()
            return .success
        }
        
        //下一曲
        let nextTrackCommand = remoteCommandCenter.nextTrackCommand
        nextTrackCommand.isEnabled = true
        nextTrackCommand.addTarget { [weak self] (event) -> MPRemoteCommandHandlerStatus in
            self?.playNext()
            return .success
        }
    
        //拖动播放位置
        let changePlaybackPositionCommand = remoteCommandCenter.changePlaybackPositionCommand
        changePlaybackPositionCommand.isEnabled = true
        changePlaybackPositionCommand.addTarget { [weak self] (commandEvent) -> MPRemoteCommandHandlerStatus in
            
            if let event = commandEvent as? MPChangePlaybackPositionCommandEvent {
                self?.seek(to: event.positionTime, completeHandle: { (complete) in
                    self?.startOrResume()
                })
                return .success
            } else {
                return .commandFailed
            }
            
        }
    }
    
}

extension CLAudioPlayer {
    
    //MARK: - 音频会话处理
    ///恢复默认的播放模式
    func recoverAudioBackMode() {
        let audioSession = AVAudioSession.sharedInstance()
        if audioSession.category != .soloAmbient {
            do {
                try audioSession.setActive(false, options: .notifyOthersOnDeactivation)
                try audioSession.setCategory(.soloAmbient, options: .defaultToSpeaker) //默认模式
            } catch let err {
                print("\(#function)   \(err)")
            }

        }
    }
    
    /// 设置后台播放模式
    func configAudioBackMode() {
        // 配置后台播放
        let audioSession = AVAudioSession.sharedInstance()
        if audioSession.category != .playback {
            do {
                try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
                try audioSession.setCategory(.playback, options: AVAudioSession.CategoryOptions.defaultToSpeaker)
            } catch let err {
                print("\(#function)   \(err)")
            }
        }
    }
    
    /// 消息注册
    func audioConfigNotification() {
        ///中断处理
        NotificationCenter.default.addObserver(self, selector: #selector(audioSessionInterruption(sender :)), name: AVAudioSession.interruptionNotification, object: nil)
        
        ///线路变更
        NotificationCenter.default.addObserver(self, selector: #selector(audioSessionRouteChange(sender :)), name: AVAudioSession.routeChangeNotification, object: nil)
    }
    
}

extension CLAudioPlayer {
    
    @objc private func audioSessionInterruption(sender : Notification?) {
        
        if let interruptionType = sender?.userInfo?[AVAudioSessionInterruptionTypeKey] as? AVAudioSession.InterruptionType {
            switch interruptionType {
            case .began:
                print("开始中断")
                //中断播放
                self.pause()
                let audioSession = AVAudioSession.sharedInstance()
                try? audioSession.setActive(false, options: .notifyOthersOnDeactivation)
                try? audioSession.setCategory(.soloAmbient, options: .defaultToSpeaker) //默认模式
            case .ended:
                if let interruptOption = sender?.userInfo?[AVAudioSessionInterruptionOptionKey] as? AVAudioSession.InterruptionOptions, interruptOption == .shouldResume {
                    do {
                        //Step 1 设置为混合加duck模式
                        let audioSession = AVAudioSession.sharedInstance()
                        try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
                        try audioSession.setCategory(.playback, options:[.mixWithOthers, .duckOthers])
                        
                        print(audioSession.categoryOptions)
                        
                        self.startOrResume()
                        
                        try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
                        try audioSession.setCategory(.playback, options: .defaultToSpeaker)
                        
                        print(audioSession.categoryOptions)
                        //Step 2 播放音频
                        
                    } catch let err {
                        print("\(#function)   \(err)")
                    }
                    
                }
            }
        }
        
    }
    
    @objc private func audioSessionRouteChange(sender : Notification?) {
        
        if let changeReason = sender?.userInfo?[AVAudioSessionRouteChangeReasonKey] as? AVAudioSession.RouteChangeReason {
            switch changeReason {
            case .newDeviceAvailable:
                // 插入耳机 恢复播放
                print("\(#function)   newDeviceAvailable")
                self.startOrResume()
            case .oldDeviceUnavailable:
                // 拔出耳机 停止播放
                print("\(#function)   oldDeviceUnavailable")
                self.pause()
            default:
                print("\(#function)   未知")
            }
            
        }
        
    }
}
